/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package baseObjects;

import GUI.myTextButton;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import pipeline.KeyboardCandidate;
import pipeline.Permuter;
import pipeline.TopBuffer;
import pipeline.TopBufferElements;
import pipeline.permutatorsPersistant;

/**
 *
 * @author yoav
 */
public class XML_Handler {

    public static void writeTopBackupPointToFile(String fileName, TopBufferElements top) throws IOException {
        String xml;
        BufferedWriter FoutXML = new BufferedWriter(new FileWriter(fileName));
        xml = serializeTop(top);
        FoutXML.write(xml);
        FoutXML.close();
    }

    private static String serializeTop(TopBufferElements top) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("Keyboard_Candidate", KeyboardCandidate.class);
        return xstream.toXML(top);
    }

    private static Object deserializeTop(String s) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("Keyboard_Candidate", KeyboardCandidate.class);
        return xstream.fromXML(s);
    }

    public void writeToFile(String fileName, Language table) throws IOException {
        String xml;
        BufferedWriter FoutXML = new BufferedWriter(new FileWriter(fileName));
        xml = serializeSymbols(table);
        FoutXML.write(xml);
        FoutXML.close();
    }

    public static void writeBackupPointToFile(String fileName, permutatorsPersistant table) throws IOException {
        String xml;
        BufferedWriter FoutXML = new BufferedWriter(new FileWriter(fileName));
        xml = serializePermutators(table);
        FoutXML.write(xml);
        FoutXML.close();
    }

    public static void writeKeyboardToFile(String fileName, Hashtable<String, myTextButton> keyboardButtons) throws IOException {
        String xml;
        BufferedWriter FoutXML = new BufferedWriter(new FileWriter(fileName));
        xml = serializeButtons(keyboardButtons);
        FoutXML.write(xml);
        FoutXML.close();
    }

    public Object readfile(String FileName) throws Exception {
        //buffered contects file XML file
        StringBuffer contents = new StringBuffer();
        //the read buffer
        BufferedReader input;

        try {//if file exist

            FileReader fXML = new FileReader(FileName);
            input = new BufferedReader(fXML);
        }//file doesnt exist yet
        catch (FileNotFoundException ex) {
            input = null;
            throw new FileNotFoundException("file not found");

        }
        //-------------------------------------file exsist - trying to read data----------------------------
        try {//try to access file

            try {//try to buffer read from file
                //line of file we read

                String line = null;
                while ((line = input.readLine()) != null) {

                    contents.append(line);//add line to contents
                    contents.append(System.getProperty("line.separator"));//apply relenvant end of line
                }

            } catch (Exception ex) {
                throw new Exception("buffer read exception", ex);
            } finally {//always close file
                input.close();
                if (contents.toString().equals("<null/>\r\n")) {
                    throw new Exception("file is empty");
                }
            }
        } catch (IOException ex) {
            throw new IOException("error in trying to access DB file", ex);
        }
        //-----------------------------apply relevant deserialized method-------------------------

        return deserializeSymbols(contents.toString());
    }

    public static Object readfileTop(String FileName) throws Exception {
        //buffered contects file XML file
        StringBuffer contents = new StringBuffer();
        //the read buffer
        BufferedReader input;

        try {//if file exist

            FileReader fXML = new FileReader(FileName);
            input = new BufferedReader(fXML);
        }//file doesnt exist yet
        catch (FileNotFoundException ex) {
            input = null;
            throw new FileNotFoundException("file not found");

        }
        //-------------------------------------file exsist - trying to read data----------------------------
        try {//try to access file

            try {//try to buffer read from file
                //line of file we read

                String line = null;
                while ((line = input.readLine()) != null) {

                    contents.append(line);//add line to contents
                    contents.append(System.getProperty("line.separator"));//apply relenvant end of line
                }

            } catch (Exception ex) {
                throw new Exception("buffer read exception", ex);
            } finally {//always close file
                input.close();
                if (contents.toString().equals("<null/>\r\n")) {
                    throw new Exception("file is empty");
                }
            }
        } catch (IOException ex) {
            throw new IOException("error in trying to access DB file", ex);
        }
        //-----------------------------apply relevant deserialized method-------------------------

        return deserializeTop(contents.toString());
    }

    public static Object readPersistantfile(String FileName) throws Exception {
        //buffered contects file XML file
        StringBuffer contents = new StringBuffer();
        //the read buffer
        BufferedReader input;

        try {//if file exist

            FileReader fXML = new FileReader(FileName);
            input = new BufferedReader(fXML);
        }//file doesnt exist yet
        catch (FileNotFoundException ex) {
            input = null;
            throw new FileNotFoundException("file not found");

        }
        //-------------------------------------file exsist - trying to read data----------------------------
        try {//try to access file

            try {//try to buffer read from file
                //line of file we read

                String line = null;
                while ((line = input.readLine()) != null) {

                    contents.append(line);//add line to contents
                    contents.append(System.getProperty("line.separator"));//apply relenvant end of line
                }

            } catch (Exception ex) {
                throw new Exception("buffer read exception", ex);
            } finally {//always close file
                input.close();
                if (contents.toString().equals("<null/>\r\n")) {
                    throw new Exception("file is empty");
                }
            }
        } catch (IOException ex) {
            throw new IOException("error in trying to access DB file", ex);
        }
        //-----------------------------apply relevant deserialized method-------------------------

        return deserializePermutators(contents.toString());
    }

    public static String intToString(int num, int digits, char tralingDigit) {
        // create variable length array of zeros
        char[] zeros = new char[digits];
        Arrays.fill(zeros, tralingDigit);
        // format number as String
        DecimalFormat df = new DecimalFormat(String.valueOf(zeros));
        return df.format(num);
    }

    public void scanAndParseXML(Language lang, Hashtable<String, myTextButton> keyboardButtons) {
        Vector<Symbol> symbols = lang.getSymbolsSortet();
        Iterator<Symbol> it = symbols.iterator();
        Symbol symbol = (Symbol) it.next();

        //------------------------------------------------------------------------------first row init-----------------------------------------------------------------------------
        for (int i = 1; i <= 13; i++) {
            //001->013
            String result = intToString(i, 3, '0');
            //   System.out.print(result);
            updateButt(keyboardButtons, result, symbol);
            if (it.hasNext()) {
                symbol = it.next();
            } else {
                return;
            }
        }
        //------------------------------------------------------------------------------second row init-----------------------------------------------------------------------------
        for (int i = 1; i <= 13; i++) {
            //101->113
            String result = "1" + intToString(i, 2, '0');
            updateButt(keyboardButtons, result, symbol);
            if (it.hasNext()) {
                symbol = it.next();
            } else {
                return;
            }
            //System.out.println(result);
        }
        //------------------------------------------------------------------------------3rd row init-----------------------------------------------------------------------------
        for (int i = 1; i <= 11; i++) {
            //201->211
            String result = "2" + intToString(i, 2, '0');
            updateButt(keyboardButtons, result, symbol);
            if (it.hasNext()) {
                symbol = it.next();
            } else {
                return;
            }
            //System.out.println(result);
        }
        //------------------------------------------------------------------------------4th row init-----------------------------------------------------------------------------
        for (int i = 1; i <= 10; i++) {
            //301->310
            String result = "3" + intToString(i, 2, '0');
            updateButt(keyboardButtons, result, symbol);
            if (it.hasNext()) {
                symbol = it.next();
            } else {
                return;
            }
            //System.out.println(result);
        }



    }

    private static String serializePermutators(permutatorsPersistant perm) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("permutatorsCollection", permutatorsPersistant.class);
        xstream.alias("permutator", Permuter.class);
        xstream.alias("Symbol", Symbol.class);

        return xstream.toXML(perm);
    }

    private String serializeSymbols(Language lang) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("Symbol", Symbol.class);
        xstream.alias("Language", Language.class);

        return xstream.toXML(lang);
    }

    private static String serializeButtons(Hashtable<String, myTextButton> keyboardButtons) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("myButton", myTextButton.class);
        xstream.alias("Keyboard", Hashtable.class);
        return xstream.toXML(keyboardButtons);
    }

    private Object deserializeSymbols(String s) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("Symbol", Symbol.class);
        xstream.alias("Language", Language.class);
        return xstream.fromXML(s);
    }

    private static Object deserializePermutators(String s) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("Symbol", Symbol.class);
        xstream.alias("permutatorsCollection", permutatorsPersistant.class);
        xstream.alias("permutator", Permuter.class);
        return xstream.fromXML(s);
    }

    public static void updateButt(Hashtable<String, myTextButton> keyboardButtons, String result, Symbol symbol) {
        myTextButton tempButt = keyboardButtons.get(result);
        //   System.out.println(" " + symbol.getRegular().toString());
        tempButt.setRegularLabel(symbol.getRegular().toString());
        if (symbol.getShift() != null) {
            tempButt.setShiftLabel(symbol.getShift().toString());
        }
        if (symbol.getCtrl() != null) {
            tempButt.setCtrlLabel(symbol.getCtrl().toString());
        }
        if (symbol.getAlt() != null) {
            tempButt.setAltLabel(symbol.getAlt().toString());
        }

    }
}
